package com.party.admin.biz.system;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.party.common.constant.Constant;
import com.party.common.utils.LangUtils;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.member.Member;
import com.party.core.model.member.MemberGroup;
import com.party.core.model.system.MemberSysRole;
import com.party.core.model.system.RoleEnum;
import com.party.core.model.system.RoleType;
import com.party.core.model.system.SysRole;
import com.party.core.service.member.IMemberGroupService;
import com.party.core.service.member.IMemberService;
import com.party.core.service.system.IMemberSysRoleService;
import com.party.core.service.system.ISysRoleService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author yifeng
 * @createTime 2018/1/24 0024 下午 17:56
 * @description 角色业务处理
 */
@Service
public class RoleBizService {
    @Autowired
    private ISysRoleService sysRoleService;
    @Autowired
    private IMemberService memberService;
    @Autowired
    private IMemberSysRoleService memberSysRoleService;
    @Autowired
    private IMemberGroupService memberGroupService;
    @Autowired
    private MemberGroupBizService memberGroupBizService;


    /**
     * 角色集合是否用户某个角色或者某个类型的角色
     *
     * @param sysRoles     角色集合
     * @param roleCode     角色代码
     * @param roleTypeCode 角色类型代码
     * @return
     */
    public boolean hasRole(List<SysRole> sysRoles, String roleCode, Integer roleTypeCode) {
        boolean has = false;
        for (SysRole sysRole : sysRoles) {
            if (null != roleCode) {
                if (sysRole.getCode().equals(roleCode)) {
                    has = true;
                    break;
                }
            } else if (null != roleTypeCode) {
                if (sysRole.getType().equals(roleTypeCode)) {
                    has = true;
                    break;
                }
            }
        }
        return has;
    }

    /**
     * 分配/取消角色
     *
     * @param roleIds  角色ids
     * @param memberId 用户id
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void assignRole(String roleIds, String memberId) {
        List<String> newRoleIds = Lists.newArrayList();
        if (StringUtils.isNotEmpty(roleIds)) {
            Member member = memberService.get(memberId);
            boolean hasAdmin = Boolean.FALSE;
            boolean hasPartner = Boolean.FALSE;
            boolean hasCosponsor = Boolean.FALSE;

            Set<String> ids = new HashSet<String>(Arrays.asList(roleIds.split(",")));
            List<String> list = Arrays.asList(roleIds.split(","));
            newRoleIds = new ArrayList<String>(list);

            List<SysRole> sysRoles = sysRoleService.batchList(ids, null, null);
            boolean hasSystemRoleType = this.hasRole(sysRoles, null, RoleType.SYSTEM_ROLE.getCode());
            if (hasSystemRoleType) {
                // 分销商
                boolean hasDistributor = this.hasRole(sysRoles, RoleEnum.DISTRIBUTOR_ROLE.getCode(), null);
                if (hasDistributor) {
                    member.setIsDistributor(YesNoStatus.YES.getCode());
                    member.setType(Constant.MEMBER_PERSONAL);
                } else {
                    member.setIsDistributor(YesNoStatus.NO.getCode());
                }
                // 合作商
                hasPartner = this.hasRole(sysRoles, RoleEnum.PARTNER_ROLE.getCode(), null);
                if (hasPartner) {
                    member.setIsPartner(YesNoStatus.YES.getCode());
                    member.setType(Constant.MEMBER_ORGANIZATION);
                } else {
                    member.setIsPartner(YesNoStatus.NO.getCode());
                }
                // 联合发起人
                boolean hasCopartner = this.hasRole(sysRoles, RoleEnum.COPARTNER_ROLE.getCode(), null);
                if (hasCopartner) {
                    member.setType(Constant.MEMBER_PERSONAL);
                    member.setIsCopartner(YesNoStatus.YES.getCode());
                } else {
                    member.setIsCopartner(YesNoStatus.NO_NEW.getCode());
                }
                // 管理员
                hasAdmin = this.hasRole(sysRoles, RoleEnum.ADMIN_ROLE.getCode(), null);
                if (hasAdmin) {
                    member.setIsAdmin(YesNoStatus.YES.getCode());
                    member.setType(Constant.MEMBER_PLATFORM);
                } else {
                    member.setIsAdmin(YesNoStatus.NO.getCode());
                }
                if (!hasAdmin && !hasPartner) {
                    // 达人
                    boolean hasExpert = this.hasRole(sysRoles, RoleEnum.EXPERT_ROLE.getCode(), null);
                    if (hasExpert) {
                        member.setIsExpert(YesNoStatus.YES.getCode());
                        member.setType(Constant.MEMBER_PERSONAL);
                    } else {
                        member.setIsExpert(YesNoStatus.NO.getCode());
                    }
                }
                hasCosponsor = this.hasRole(sysRoles, RoleEnum.COSPONSOR_ROLE.getCode(), null);
                if (hasCosponsor) {
                    member.setIsCosponsor(YesNoStatus.YES.getCode());
                    member.setType(Constant.MEMBER_ORGANIZATION);
                } else {
                    member.setIsCosponsor(YesNoStatus.NO.getCode());
                }
            }

            if (!hasPartner) {
                // 套餐角色或功能角色——合作商
                boolean hasBusinessRoleType = this.hasRole(sysRoles, null, RoleType.BUSINESS_ROLE.getCode());
                if (hasBusinessRoleType) {
                    member.setIsPartner(YesNoStatus.YES.getCode());
                    member.setType(Constant.MEMBER_ORGANIZATION);
                } else {
                    member.setIsPartner(YesNoStatus.NO.getCode());
                }
            }

            if (!hasAdmin) {
                // 平台管理员角色
                boolean hasPlatformRoleType = this.hasRole(sysRoles, null, RoleType.PLATFORM_ROLE.getCode());
                if (hasPlatformRoleType) {
                    member.setIsAdmin(YesNoStatus.YES.getCode());
                    member.setType(Constant.MEMBER_PLATFORM);
                } else {
                    member.setIsAdmin(YesNoStatus.NO.getCode());
                }
            }

            if (YesNoStatus.YES.getCode().equals(member.getIsPartner())
                    || YesNoStatus.YES.getCode().equals(member.getIsAdmin())) {
                member.setIsExpert(YesNoStatus.NO.getCode());
                for (SysRole sysRole : sysRoles) {
                    if (sysRole.getCode().equals(RoleEnum.EXPERT_ROLE.getCode())) {
                        newRoleIds.remove(sysRole.getId());
                        break;
                    }
                }
            }

            if (!(hasCosponsor || hasPartner || hasAdmin)) {
                member.setType(Constant.MEMBER_PERSONAL);
            }

            member.setUpdateDate(null);
            memberService.update(member);


            for (String roleId : newRoleIds) {
                SysRole sysRole = sysRoleService.get(roleId);
                if (!sysRole.getCode().equals(RoleEnum.ADMIN_ROLE.getCode())
                        && !sysRoleService.hasRole(memberId, sysRole.getCode())) {
                    MemberSysRole memberSysRole = new MemberSysRole(memberId, roleId);
                    memberSysRoleService.insert(memberSysRole);
                }
            }
        } else {
            Member member = memberService.get(memberId);
            member.setIsDistributor(YesNoStatus.NO.getCode());
            member.setIsExpert(YesNoStatus.NO.getCode());
            member.setIsAdmin(YesNoStatus.NO.getCode());
            member.setIsPartner(YesNoStatus.NO.getCode());
            member.setIsCopartner(YesNoStatus.NO_NEW.getCode());
            member.setIsCosponsor(YesNoStatus.NO.getCode());
            member.setType(Constant.MEMBER_PERSONAL);
            member.setUpdateDate(null);
            memberService.update(member);
        }

        List<SysRole> sysRoles = sysRoleService.findByMemberId(memberId);
        List<String> oldRoleIds = LangUtils.transform(sysRoles, new Function<SysRole, String>() {
            @Override
            public String apply(SysRole input) {
                return input.getId();
            }
        });
        oldRoleIds.removeAll(newRoleIds);
        for (String oldRoleId : oldRoleIds) {
            memberSysRoleService.deleteByRoleIdAndMemberId(oldRoleId, memberId);
        }
    }

    /**
     * 去分配角色
     *
     * @param identity 身份
     */
    public Map<String, List<SysRole>> toAssignRole(String identity, Integer type) {
        Map<String, List<SysRole>> systemMap = new LinkedHashMap<String, List<SysRole>>();

        Map<Integer, String> convertMap = RoleType.convertMap();
        if (identity.equals(RoleEnum.PARTNER_ROLE.getCode())) {
            convertMap.remove(RoleType.SYSTEM_ROLE.getCode());
            convertMap.remove(RoleType.PLATFORM_ROLE.getCode());
            convertMap.remove(RoleType.KNOWLEDGE_MANAGEMENT_ROLE.getCode());
        } else if (identity.equals(RoleEnum.COPARTNER_ROLE.getCode())
                || identity.equals(RoleEnum.DISTRIBUTOR_ROLE.getCode())
                || identity.equals("normal")) {
            convertMap.remove(RoleType.PLATFORM_ROLE.getCode());
            convertMap.remove(RoleType.PARTNER_ROLE.getCode());
            convertMap.remove(RoleType.BUSINESS_ROLE.getCode());
            convertMap.remove(RoleType.KNOWLEDGE_MANAGEMENT_ROLE.getCode());
        } else if (identity.equals(RoleEnum.ADMIN_ROLE.getCode())) {
            convertMap.remove(RoleType.SYSTEM_ROLE.getCode());
            convertMap.remove(RoleType.PARTNER_ROLE.getCode());
            convertMap.remove(RoleType.BUSINESS_ROLE.getCode());
            convertMap.remove(RoleType.KNOWLEDGE_MANAGEMENT_ROLE.getCode());
        }
        for (Map.Entry<Integer, String> mm : convertMap.entrySet()) {
            SysRole sysRole = new SysRole();
            sysRole.setType(mm.getKey());
            sysRole.setDelFlag(BaseModel.DEL_FLAG_NORMAL);
            List<SysRole> sysRoles = sysRoleService.list(sysRole);
            List<SysRole> newSysRoles = Lists.newArrayList();
            for (SysRole role : sysRoles) {
                newSysRoles.add(role);
                if (mm.getKey().equals(RoleType.SYSTEM_ROLE.getCode())) {
                    // 合作商
                    if (identity.equals(RoleEnum.PARTNER_ROLE.getCode())) {
//                        if (!(role.getCode().equals(RoleEnum.PARTNER_ROLE.getCode())
//                                || role.getCode().equals(RoleEnum.COSPONSOR_ROLE.getCode()))) {
//                            newSysRoles.remove(role);
//                        }
                    }
                    // CEO户外联盟
                    if (identity.equals(RoleEnum.COPARTNER_ROLE.getCode())) {

                    }
                    // 分销商
                    if (identity.equals(RoleEnum.DISTRIBUTOR_ROLE.getCode())) {
                        if (!(role.getCode().equals(RoleEnum.DISTRIBUTOR_ROLE.getCode())
                                || role.getCode().equals(RoleEnum.EXPERT_ROLE.getCode()))) {
                            newSysRoles.remove(role);
                        }
                    }
                    // 普通用户
                    if (identity.equals("normal")) {
                        if (!(role.getCode().equals(RoleEnum.DISTRIBUTOR_ROLE.getCode())
                                || role.getCode().equals(RoleEnum.EXPERT_ROLE.getCode())
                                || role.getCode().equals(RoleEnum.ADMIN_ROLE.getCode())
                                || role.getCode().equals(RoleEnum.PARTNER_ROLE.getCode()))) {
                            newSysRoles.remove(role);
                        }
                    }

                    if (null != type) {
                        // 机构
                        if (type.equals(Constant.MEMBER_ORGANIZATION)) {
                            if (!(role.getCode().equals(RoleEnum.PARTNER_ROLE.getCode())
                                    || role.getCode().equals(RoleEnum.COPARTNER_ROLE.getCode()))) {
                                newSysRoles.remove(role);
                            }
                        }
                        // 个人
                        if (type.equals(Constant.MEMBER_PERSONAL)) {
                            if (role.getCode().equals(RoleEnum.ADMIN_ROLE.getCode())
                                    || role.getCode().equals(RoleEnum.PARTNER_ROLE.getCode())
                                    || role.getCode().equals(RoleEnum.COSPONSOR_ROLE.getCode())) {
                                newSysRoles.remove(role);
                            }
                        }
                        if (type.equals(Constant.MEMBER_PLATFORM)) {
                            if (!role.getCode().equals(RoleEnum.ADMIN_ROLE.getCode())) {
                                newSysRoles.remove(role);
                            }
                        }
                    }
                }
            }
            systemMap.put(mm.getValue(), newSysRoles);
        }
        return systemMap;
    }

    /**
     * 分配/取消角色
     *
     * @param roleIds  角色ids
     * @param memberId 用户id
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void assignRoleMemberGroup(String roleIds, String memberId) {
        MemberGroup memberGroup = memberGroupService.get(memberId);
        List<String> childIds = memberGroupService.getChild(memberId);
        boolean hasChild = childIds.size() > 0 ? true : false;
        boolean isMainAccount = StringUtils.isEmpty(memberGroup.getPartnerId()) ? true : false;
        boolean addChildPartner = false;
        boolean addChildXzgs = false;

        List<String> newRoleIds = Lists.newArrayList();
        if (StringUtils.isNotEmpty(roleIds)) {
            boolean hasAdmin = Boolean.FALSE;
            boolean hasPartner = Boolean.FALSE;
            boolean hasCosponsor = Boolean.FALSE;

            Set<String> ids = new HashSet<String>(Arrays.asList(roleIds.split(",")));
            List<String> list = Arrays.asList(roleIds.split(","));
            newRoleIds = new ArrayList<String>(list);

            List<SysRole> sysRoles = sysRoleService.batchList(ids, null, null);
            boolean hasSystemRoleType = this.hasRole(sysRoles, null, RoleType.SYSTEM_ROLE.getCode());
            if (hasSystemRoleType) {
                // 合作商
                hasPartner = this.hasRole(sysRoles, RoleEnum.PARTNER_ROLE.getCode(), null);
                if (hasPartner) {
                    memberGroup.setIsPartner(YesNoStatus.YES.getCode());
                    memberGroup.setType(Constant.MEMBER_ORGANIZATION);

                    if (hasChild) {
                        addChildPartner = true;
                    }
                } else {
                    memberGroup.setIsPartner(YesNoStatus.NO.getCode());
                }

                boolean hasXzgs = this.hasRole(sysRoles, RoleEnum.KNOWING_COMMUNE_ROLE.getCode(), null);
                if (hasXzgs && hasChild) {
                    addChildXzgs = true;
                }

                // 管理员
                hasAdmin = this.hasRole(sysRoles, RoleEnum.ADMIN_ROLE.getCode(), null);
                if (hasAdmin) {
                    memberGroup.setIsAdmin(YesNoStatus.YES.getCode());
                    memberGroup.setType(Constant.MEMBER_PLATFORM);
                } else {
                    memberGroup.setIsAdmin(YesNoStatus.NO.getCode());
                }
                hasCosponsor = this.hasRole(sysRoles, RoleEnum.COSPONSOR_ROLE.getCode(), null);
                if (hasCosponsor) {
                    memberGroup.setIsCosponsor(YesNoStatus.YES.getCode());
                    memberGroup.setType(Constant.MEMBER_ORGANIZATION);
                } else {
                    memberGroup.setIsCosponsor(YesNoStatus.NO.getCode());
                }
            }

            if (!hasPartner) {
                // 套餐角色或功能角色——合作商
                boolean hasBusinessRoleType = this.hasRole(sysRoles, null, RoleType.BUSINESS_ROLE.getCode());
                if (hasBusinessRoleType) {
                    memberGroup.setIsPartner(YesNoStatus.YES.getCode());
                    memberGroup.setType(Constant.MEMBER_ORGANIZATION);
                } else {
                    memberGroup.setIsPartner(YesNoStatus.NO.getCode());
                }
            }

            if (!hasAdmin) {
                // 平台管理员角色
                boolean hasPlatformRoleType = this.hasRole(sysRoles, null, RoleType.PLATFORM_ROLE.getCode());
                if (hasPlatformRoleType) {
                    memberGroup.setIsAdmin(YesNoStatus.YES.getCode());
                    memberGroup.setType(Constant.MEMBER_PLATFORM);
                    hasAdmin = true;
                } else {
                    memberGroup.setIsAdmin(YesNoStatus.NO.getCode());
                }
            }

            if (YesNoStatus.YES.getCode().equals(memberGroup.getIsPartner())
                    || YesNoStatus.YES.getCode().equals(memberGroup.getIsAdmin())) {
                for (SysRole sysRole : sysRoles) {
                    if (sysRole.getCode().equals(RoleEnum.EXPERT_ROLE.getCode())) {
                        newRoleIds.remove(sysRole.getId());
                        break;
                    }
                }
            }

            if (!(hasCosponsor || hasPartner || hasAdmin)) {
                memberGroup.setType(Constant.MEMBER_PERSONAL);
            }

            memberGroup.setUpdateDate(null);
            memberGroupService.update(memberGroup);


            for (String roleId : newRoleIds) {
                SysRole sysRole = sysRoleService.get(roleId);
                if (!sysRole.getCode().equals(RoleEnum.ADMIN_ROLE.getCode())
                        && !sysRoleService.hasRole(memberId, sysRole.getCode())) {
                    MemberSysRole memberSysRole = new MemberSysRole(memberId, roleId);
                    memberSysRoleService.insert(memberSysRole);
                }
            }
        } else {
            memberGroup.setIsAdmin(YesNoStatus.NO.getCode());
            memberGroup.setIsPartner(YesNoStatus.NO.getCode());
            memberGroup.setIsCosponsor(YesNoStatus.NO.getCode());
            memberGroup.setType(Constant.MEMBER_PERSONAL);
            memberGroup.setUpdateDate(null);
            memberGroupService.update(memberGroup);
        }

        List<SysRole> sysRoles = sysRoleService.findByMemberId(memberId);
        List<String> oldRoleIds = LangUtils.transform(sysRoles, new Function<SysRole, String>() {
            @Override
            public String apply(SysRole input) {
                return input.getId();
            }
        });
        oldRoleIds.removeAll(newRoleIds);
        for (String oldRoleId : oldRoleIds) {
            memberSysRoleService.deleteByRoleIdAndMemberId(oldRoleId, memberId);
        }

        if (hasChild && isMainAccount) {
            for (String childId : childIds) {
                List<String> childIds2 = memberGroupService.getChild(childId);
                for (String s : childIds2) {
                    if (addChildPartner) {
                        memberGroupBizService.addPartner(s, false);
                    }
                }
                if (addChildPartner) {
                    memberGroupBizService.addPartner(childId, true);
                }
                if (addChildXzgs) {
                    memberGroupBizService.addXzgs(childId);
                }
            }
        }
    }
}
